package org.mtree.context;

import java.util.Collection;
import java.util.function.BiConsumer;

/**
 * 上下文
 * 
 * @author rushman
 */
public interface Context {

    /**
     * 取上下文属性值
     * 
     * @param name 属性名，不可为空
     * @return {@code Object} 属性值，如果找不到值，则返回空
     */
    public Object get(String name);

    /**
     * 设置上下文属性值
     * 
     * @param name 属性名，不可为空
     * @param value {@code Object} 属性值，可以为空
     * @return {@code Object} 原属性值
     */
    public Object set(String name, Object value);

    /**
     * 删除上下文属性
     * 
     * @param name 属性名，不可未空
     * @return {@code Object} 原属性值
     */
    public Object remove(String name);

    /**
     * 检查上下文是否包含属性
     * 
     * @param name 属性名，不可为空
     * @return {@code boolean}
     */
    public boolean has(String name);

    /**
     * 取上下文属性名（集合）
     * 
     * @return {@code Collection<String>} 属性名集合
     */
    public Collection<String> nameSet();

    /**
     * 取指定类型的上下文属性值
     * 
     * @param name 属性名，不可为空
     * @param type {@code Class<T>} 值类型，不可为空
     * @return {@code T} 属性值，如果找不到指定类型的值，则返回空
     */
    @SuppressWarnings("unchecked")
    default public <T> T get(String name, Class<T> type) {
        Object value = get(name);
        if (value == null || !type.isInstance(value)) {
            return null;
        }
        return (T) value;
    }

    /**
     * 取上下文属性值，如果该值不存在（或类型不匹配），则返回默认值
     * 
     * @param name 属性名，不可为空
     * @param defaultValue {@code T} 默认值
     * @return {@code T} 属性值，如果找不到值，则返回默认值
     */
    @SuppressWarnings("unchecked")
    default public <T> T get(String name, T defaultValue) {
        Object value = this.get(name);
        try {
            return value == null ? defaultValue : (T) value;
        } catch (Exception e) {
            return defaultValue;
        }
    }

    /**
     * 遍历上下文属性
     * 
     * @param consumer 
     */
    default public void forEach(BiConsumer<String, Object> consumer) {
        for (String propName : this.nameSet()) {
            consumer.accept(propName, this.get(propName));
        }
    }

}
